package com.fyp.speachrecognition;

import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Locale;
import java.util.StringTokenizer;

import com.fyp.MediaPlayer.MediaPlayerLibrary;
import com.fyp.settings.FileNames;
import com.fyp.settings.SettingsMain;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.PhoneLookup;
import android.speech.RecognizerIntent;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.view.View.OnClickListener;
public class SaveContact extends Activity implements OnInitListener{
	private static final int VR_REQUEST = 100; 

	private final String LOG_TAG = "Speech Dialer Save Contact";
	String Dial="";
	private int MY_DATA_CHECK_CODE = 0;
	 private TextToSpeech myTTS;
	boolean flag=true;
	int NUMBER=1,NAME=2,SAVE=3;
	int action=0;
	 EditText ContactNo, ContactName;
	 private ListView wordList;
	 MediaPlayer mrL= null;
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		Intent i=this.getIntent();
		Bundle b=i.getExtras();
		
		if(!((Boolean) b.get("Login_success")))
		{
			finish();
		}
		else
		{
			setContentView(R.layout.save_contact_xml);
			 mrL= MediaPlayerLibrary.startPlayingFromRaw(this, R.raw.recrd_save_menu);
				
				
		
		
		ContactNo=(EditText) findViewById(R.id.NumberForSave);
		ContactName=(EditText) findViewById(R.id.ContactNameForSave);
		Log.v("Activity", "Save Contact Activity");
		
		 wordList = (ListView) findViewById(R.id.resultContact);
        // Listening to Login Screen link
              
        Button contactSaveBtn = (Button) findViewById(R.id.no_speek__prompt_btn);
       
        contactSaveBtn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if(MediaPlayerLibrary.isPlaying())
				{
					mrL.stop();
					mrL.release();
					MediaPlayerLibrary.setPlaying(false);
				}
				//savContactBusinessLogic(ContactName.getText().toString(),ContactNo.getText().toString());
				
				Intent listenIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
	        	listenIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());
	        	listenIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Say a word!");
	        	listenIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
	        	listenIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 10);
	            startActivityForResult(listenIntent, VR_REQUEST);
			}
		});
        
        Intent checkTTSIntent = new Intent();
    	checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
    	startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
		}
        
	};
	private String constructString(String wordChosen) {
		// TODO Auto-generated method stub
		StringBuilder sb = new StringBuilder();
		String[] s=wordChosen.split("[ ]");
		int i=0;
    	
			while (i<s.length)
			{
				sb.append(s[i]);
				i++;
			}
		
		
		return sb.toString().trim();
	}
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		  
		  action=0;
		  if (requestCode == MY_DATA_CHECK_CODE) {
		        if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
		            myTTS = new TextToSpeech(this, this);
		        }
		        else {
		            Intent installTTSIntent = new Intent();
		            installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
		            startActivity(installTTSIntent);
		        }
		}
	    if (requestCode == VR_REQUEST && resultCode == RESULT_OK) 
	    {
	        ArrayList<String> suggestedWords = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
	        wordList.setAdapter(new ArrayAdapter<String> (this, R.layout.word, suggestedWords));
	        ListIterator<String> it = suggestedWords.listIterator();
	        flag=true;
	        while(it.hasNext())
	        {
	        	String wordChosen = it.next();
	        	Log.v(LOG_TAG, "auto word chosen for save: "+wordChosen);
	        	wordChosen.trim();
	        	
	        	wordChosen = constructString(wordChosen.toLowerCase());
	        	
	        	if(ContactName.getText().length()==0)
	        	{
		        			 
		        				 ContactName.setText(wordChosen);
		        				 myTTS.speak(wordChosen, TextToSpeech.QUEUE_FLUSH, null);
		        				 action=NAME;
		        				 flag=false;
		        			 break;
		        }
		        		 
		            	
		        	 
	        	else 
	        	{
	        		
		        		if(ContactNo.getText().length()==0)
		        		{
		        			Log.v(LOG_TAG, "Contact No empty: "+wordChosen);
		        			StringTokenizer st = new StringTokenizer(wordChosen," ");
		        			String s="";
		        			Dial="";
		        			while(st.hasMoreTokens())
		        			{
		        				s= st.nextToken();
		            		 
		            		
			            		if(isInteger(s))
			            		{
			            			Log.v(LOG_TAG, "Number Tokens: "+s);
			            			
			            			Dial=Dial+s;
			            			action=NUMBER;
			            			flag=false;
			            		}
			            		else
			            		{
			            			Log.v(LOG_TAG, "Token (Error Block where No not found): "+s);
			            			Dial="";
			            			action=0;
			            			flag=true;
			            			break;
			            		}
		            		
		        			}
		        		}
		        		
		        		else 
		        		{
		        			if((wordChosen.contains("phone book"))||(wordChosen.equalsIgnoreCase("save")))
				        	 {
				        		 Log.v(LOG_TAG, "Token: SAVE");
				        		action=SAVE;
				        		flag=false;
				        	 }
		        			else
		        			{
		        				action=0;
		            			flag=true;
		        			}
			        		
		        		}
		             
		        	
	        	}
        		
	        	
	        	
	        	 
	         		
	            	
	        	 
	        	if(!flag)
	        	{
	        		break;
	        	}
	        }
	        
	        if(action==NUMBER)
	        {
	        	Log.v(LOG_TAG, "Dial: "+Dial);
	        	ContactNo.setText(Dial);
	        	myTTS.speak(Dial, TextToSpeech.QUEUE_FLUSH, null);
				Dial="";
				
				
	        	ContactName.setSelected(true);
	        }
	        else if(action==NAME)
	        {
	        	mrL= MediaPlayerLibrary.startPlayingFromRaw(this, R.raw.recrd_number_save);
	        	
	        	Toast.makeText(SaveContact.this, "Speak Number", Toast.LENGTH_SHORT).show();
	        }
	        else if(action==SAVE)
	        {
	        	if(!contactExists(this,ContactNo.getText().toString(),ContactName.getText().toString()))
	        	{
	        	savContactBusinessLogic(ContactName.getText().toString(),ContactNo.getText().toString());

	        	mrL= MediaPlayerLibrary.startPlayingFromRaw(this, R.raw.save_number_prmt);
	        	Toast.makeText(SaveContact.this, "Contact Saved", Toast.LENGTH_SHORT).show();
	        	}
	        	else
	        	{
	        		mrL= MediaPlayerLibrary.startPlayingFromRaw(this, R.raw.recrd_saving_error);
	        		Toast.makeText(SaveContact.this, "Contact Alredy Exists", Toast.LENGTH_SHORT).show();
	        	}
	 	        	action=9;
	        }
	        else if(action==0)
	        {

	        	mrL= MediaPlayerLibrary.startPlayingFromRaw(this, R.raw.no_keyword_match);
	        	Toast.makeText(SaveContact.this, "Recognition Failed", Toast.LENGTH_SHORT).show();
	        }
	        
	    }
	    
	  
	    super.onActivityResult(requestCode, resultCode, data);
	}
	private boolean contactExists(Context ctx,String incommingNumber,String name)
	{
		Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(incommingNumber));
	    Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null);
	    try {
	        if (cur.moveToFirst()) 
	        {
	            do 
	            {
	                if (cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) 
	                {
	                    return true;
	                }

	            } while (cur.moveToNext());
	        }

	    } catch (Exception e) {
	        System.out.println(e.getStackTrace());
	    }
	    return false;
    }
	
	 public void savContactBusinessLogic(String Name,String No) {
	      


	        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
	        int rawContactInsertIndex = ops.size();
	        ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
	        		.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
	        		.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
	        		.build()
	        		);

	        //------------------------------------------------------ Names
	       /* if((Name != null||!Name.equals(""))&&(MobileNumber != null||!MobileNumber.equals("")));
	        {*/           
	        	ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
	        			.withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex)
	        			.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
	        			.withValue(StructuredName.DISPLAY_NAME, Name)
	        			.withValue(StructuredName.GIVEN_NAME, Name)
	        			
	        			.build());
	        	ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
	        		    .withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex)
	        		    .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
	        		    .withValue(Phone.NUMBER, No)
	        		    .withValue(Phone.TYPE, Phone.TYPE_MOBILE)                
	        		    .build());
	       // }                 
                try 
                {
                   this.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
                   requestSyncNow(this);
                } 
                catch (Exception e) 
                {               
                    e.printStackTrace();
                  //  Toast.makeText(myContext, "Exception: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
	                            
	    }
	 public static void requestSyncNow( Context context) {

		   
		            AccountManager accountManager = AccountManager.get(context);
		            Account[] accounts = accountManager.getAccounts();
		            boolean isMasterSyncOn = ContentResolver.getMasterSyncAutomatically();


		            for (Account account : accounts) {
		                Log.d("SYNC", "account=" + account);

		                int isSyncable = ContentResolver.getIsSyncable(account,
		                        ContactsContract.AUTHORITY);
		                boolean isSyncOn = ContentResolver.getSyncAutomatically(account,
		                        ContactsContract.AUTHORITY);
		                Log.d("SYNC", "Syncable=" + isSyncable + " SyncOn=" + isSyncOn);
		                if (isSyncable > 0 /* && isSyncOn */) {
		                    Log.d("SYNC", "request Sync");
		                    Bundle bundle = new Bundle();
		                    bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
		                    ContentResolver.requestSync(account, ContactsContract.AUTHORITY, bundle);
		                }
		            }

		       
		   
		}
	public static boolean isInteger(String s) {
	    try { 
	        Integer.parseInt(s); 
	    } catch(NumberFormatException e) { 
	        return false; 
	    }
	    // only got here if we didn't return false
	    return true;
	}
	public void onInit(int initStatus) {
	    if (initStatus == TextToSpeech.SUCCESS) {
	        myTTS.setLanguage(Locale.UK);
	    }
	    else if (initStatus == TextToSpeech.ERROR) {
	        Toast.makeText(this, "Sorry! Text To Speech failed...", Toast.LENGTH_LONG).show();
	    }
	}
	@Override
	  protected void onResume() {
		
	    super.onResume();
	   
	  }

	  @Override
	  protected void onPause() {
		 
	    super.onPause();
	   
	    
	  }
	  protected void onDestroy()
	  {
		 myTTS.stop();
		  myTTS.shutdown();
		  super.onDestroy();
		  
	  }
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.menu, menu);
	    return true;
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	        case R.id.Configuration:
	            record();
	            return true;
	        default:
	            return super.onOptionsItemSelected(item);
	    }
	}

	private void record() {
		// TODO Auto-generated method stub
		Intent i = new Intent(getApplicationContext(), SettingsMain.class);
		startActivity(i);
	}

}
